<?php
declare(strict_types=1);

/**
 * 文件描述：微信商户进件状态同步控制台命令
 * 用途：定时批量查询微信商户进件申请状态，并更新本地 merchant 记录
 * 用法示例：
 *  - php think merchant:status-sync
 *  - php think merchant:status-sync --status=2,3,5 --page-size=100 --sleep=200
 * 说明：
 *  - 默认仅同步“已提交/待签约/待打款(账户验证)”三种需要异步回调或后续动作的状态
 */

namespace app\command;

use app\api\dao\WeChatZftDao;
use app\api\model\WeChatMerchant as WeChatMerchantModel;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\facade\Log;

/**
 * 类描述：商户进件状态同步命令
 * 责任：分页扫描需要刷新状态的商户，调用现有 DAO 的 getApplyStatus 方法更新状态与详情
 */
class MerchantStatusSync extends Command
{
    /**
     * 配置命令名称与选项
     */
    protected function configure()
    {
        $this->setName('merchant:status-sync')
            ->setDescription('批量同步微信商户进件状态（支持分页、状态过滤与节流）')
            ->addOption('status', 's', Option::VALUE_OPTIONAL, '需要同步的本地状态，逗号分隔（默认：2,3,5）')
            ->addOption('page-size', 'p', Option::VALUE_OPTIONAL, '每页处理条数', 50)
            ->addOption('max-pages', 'm', Option::VALUE_OPTIONAL, '最大处理页数（0 表示处理所有页）', 0)
            ->addOption('sleep', null, Option::VALUE_OPTIONAL, '每条记录处理后的休眠毫秒数（节流）', 0);
    }

    /**
     * 执行命令主体
     * - 根据选项构建筛选条件
     * - 分页加载商户记录并逐条调用 DAO 的 getApplyStatus 进行更新
     * - 输出进度与统计信息
     */
    protected function execute(Input $input, Output $output)
    {
        $statusOpt = trim((string)$input->getOption('status'));
        $pageSize = max(10, (int)$input->getOption('page-size'));
        $maxPages = (int)$input->getOption('max-pages');
        $sleepMs  = max(0, (int)$input->getOption('sleep'));
        // 默认需要刷新的状态：SUBMITTED(2)、TO_BE_SIGNED(3)、TO_BE_CONFIRMED(5)
        $defaultStatuses = [
            WeChatMerchantModel::STATUS['SUBMITTED'],
            WeChatMerchantModel::STATUS['TO_BE_SIGNED'],
            WeChatMerchantModel::STATUS['TO_BE_CONFIRMED'],
        ];
        $statusList = $defaultStatuses;
        if ($statusOpt !== '') {
            $statusList = array_values(array_filter(array_map('intval', explode(',', $statusOpt)), function ($v) {
                return $v >= 0;
            }));
            if (empty($statusList)) {
                $statusList = $defaultStatuses;
            }
        }
        $dao = new WeChatZftDao(0);
        $page = 1;
        $totalProcessed = 0;
        $totalUpdated = 0;
        $totalFailed = 0;
        $output->writeln('<info>开始同步商户进件状态</info>');
        $output->writeln('筛选状态: [' . implode(',', $statusList) . ']');
        $output->writeln('每页条数: ' . $pageSize . '; 最大页数: ' . ($maxPages > 0 ? $maxPages : '不限'));
        do {
            // 使用 IN 条件一次性拉取本页数据
            $where = [
                ['status', 'in', $statusList],
            ];
            $res = $dao->getPagesLists($where, $page, $pageSize);
            $list = $res['data'] ?? [];
            $totalPages = (int)($res['total_page'] ?? 0);
            if (empty($list)) {
                break; // 没有更多数据
            }
            foreach ($list as $item) {
                $totalProcessed++;
                try {
                    // 调用已有逻辑自动更新并持久化
                    $before = (int)$item['status'];
                    $updated = $dao->getApplyStatus($item);
                    $after = (int)$updated['status'];
                    $msg = sprintf('ID:%s applyment_id:%s 状态 %d => %d', (string)$item['id'], (string)$item['applyment_id'], $before, $after);
                    $output->writeln('<comment>' . $msg . '</comment>');
                    \think\facade\Log::info('[merchant:status-sync] ' . $msg);
                    $totalUpdated++;
                } catch (\Throwable $e) {
                    $totalFailed++;
                    $err = sprintf('ID:%s 同步失败：%s', (string)$item['id'], $e->getMessage());
                    $output->writeln('<error>' . $err . '</error>');
                    \think\facade\Log::error('[merchant:status-sync] ' . $err);
                }
                if ($sleepMs > 0) {
                    usleep($sleepMs * 1000);
                }
            }
            // 分页控制：达到最大页数或已到最后一页则退出
            if (($maxPages > 0 && $page >= $maxPages) || ($totalPages > 0 && $page >= $totalPages)) {
                break;
            }
            $page++;
        } while (true);
        $output->writeln('------------------------------------------------------------');
        $output->writeln('<info>同步完成</info>');
        $output->writeln('总处理: ' . $totalProcessed . '，成功: ' . $totalUpdated . '，失败: ' . $totalFailed);
        return 0;
    }
}